package org.testis.data.parser;

import org.testis.data.AtofModuleConstants;
import org.testis.webautomationmodule.data.WebAutomationModuleDataNode;
import org.testis.webautomationmodule.data.WebAutomationModuleDataObject;
import org.testis.webautomationmodule.ui.UIEnumaration.UIObjectGroup;
import org.testis.webautomationmodule.ui.UIEnumaration.UIObjectParameter;
import org.testis.webautomationmodule.ui.UIEnumaration.UIObjectType;
import java.util.ArrayList;

import org.testis.orm.refinedclasses.DynamicMapDesignTreeNode;
import org.testis.orm.refinedclasses.DynamicMapObject;
import org.testis.orm.refinedclasses.DynamicMapParameter;

/**
 *
 * @author nurhat
 */
public abstract class WAMDopDecorator {

    protected WAMDopDecorator m_nextDecoratorObject;
    private WebAutomationModuleDataObject m_data;
    private DynamicMapDesignTreeNode m_root;

    public WAMDopDecorator(WebAutomationModuleDataObject data,
            DynamicMapDesignTreeNode root) {
        setRoot(root);
        setData(data);
    }

    /**
     * Extended decorator method, special for each object
     * @return
     */
    protected abstract boolean setBehavior();

    public WAMDopDecorator getNextDecoratorObject() {
        return m_nextDecoratorObject;
    }

    /**
     * Operates current decorators special method(()), and delegates remaining job
     * to the related object(nextUIObject).
     * @return
     */
    public boolean operate() {
        if (setBehavior()) {
            if (m_nextDecoratorObject != null) {
                return m_nextDecoratorObject.operate();
            }
            return true;
        }
        return false;
    }

    /**
     * 
     * @param val
     */
    public void setNextDecoratorObject(WAMDopDecorator val) {
        this.m_nextDecoratorObject = val;

    }

    public WebAutomationModuleDataObject getData() {
        return m_data;
    }

    public void setData(WebAutomationModuleDataObject m_data) {
        this.m_data = m_data;
    }

    public DynamicMapDesignTreeNode getRoot() {
        return m_root;
    }

    public void setRoot(DynamicMapDesignTreeNode m_root) {
        this.m_root = m_root;
    }

    public void addBehaviors(ArrayList<DynamicMapDesignTreeNode> list,
            DynamicMapDesignTreeNode obj) {
        if (obj == null) {
            return;
        }

        DynamicMapDesignTreeNode[] nodes = obj.getChildren();
        if (nodes == null) {
            return;
        }
        for (int behaviorIndex = 0; behaviorIndex <
                nodes.length; behaviorIndex++) {
            String groupName = nodes[behaviorIndex].getObject().
                    getGroupName();
            if (groupName.equals(UIObjectGroup.Behaviour.name())) {
                list.add(nodes[behaviorIndex]);
            }
        }
    }

    public String findDynamicGridLocatorId(DynamicMapDesignTreeNode node) {
        DynamicMapDesignTreeNode parent = node.getParent();
        String id = null;
        if (parent == null) {
            return null;
        }
        DynamicMapObject parentObj = parent.getObject();
        if (parentObj.getTypeName().equals(
                UIObjectType.UIDynamicGrid.name())) {
            DynamicMapParameter parLocator = parentObj.getParameterByName(
                    UIObjectParameter.LocatorId.name());
            String parLocatorValue = getParameterValue(parLocator);
            if (parLocatorValue == null) {
                return null;
            } else if (!parLocatorValue.equals("")) {
                DynamicMapDesignTreeNode objLocator =
                        findObject(parLocatorValue);
                DynamicMapParameter parLocatorId = objLocator.getObject().
                        getParameterByName(
                        UIObjectParameter.Id.name());
                id = getParameterValue(parLocatorId);
            }

        }
        return id;
    }

    public void appendObjectsToList(ArrayList<DynamicMapDesignTreeNode> lst,
            ArrayList<WebAutomationModuleDataNode> lstData) {
        DynamicMapObject object;
        Object[] constArgs = null;
        DynamicMapParameter[] params;
        String objectType;
        String objectId, value, abstractId;
        boolean isObjectDynamic = false;
        for (int i = 0; i < lst.size();
                i++) {
            object = lst.get(i).getObject();
            objectType = object.getTypeName();
            objectId = getObjectId(object);
            abstractId = getAbstractId(object);
            isObjectDynamic =
                    isObjectDynamic(object);
            if (isObjectDynamic) {
                constArgs = new Object[3];
                value = (String) getValueFromDataObject(object);
                String locatorId = findDynamicGridLocatorId(lst.get(i));
                DynamicMapDesignTreeNode objValue = findObject(value);
                if (objValue != null) {
                    value = getObjectId(objValue.getObject());
                } else {
                    //to extract abstract ids given for dynamic object check issue
                    //5056
                    String[] values = value.split(
                            AtofModuleConstants.DYNAMIC_OBJECT_SPLIT_STR);
                    if (values.length > 1) {
                        String parsedValue = convertAbstractIds(values[1]);
                        value = values[0] +
                                AtofModuleConstants.DYNAMIC_OBJECT_SPLIT_STR +
                                parsedValue;
                    }
                }
                if (locatorId != null) {
                    value = locatorId +
                            AtofModuleConstants.DYNAMIC_OBJECT_SPLIT_STR + value;
                }
                constArgs[0] = objectId;
                constArgs[1] = objectType;
                constArgs[2] = value;
            } else if (objectType.equals(UIObjectType.UIFrame.name())) {
                String[] strPath = new String[2];
                strPath[0] = "relative=top";
                strPath[1] = objectId;
                constArgs = new Object[]{strPath};
            } else if (objectType.equals(UIObjectType.UIButton.name()) ||
                    objectType.equals(UIObjectType.UICheckBox.name()) ||
                    objectType.equals(UIObjectType.UIFileSelector.name()) ||
                    objectType.equals(UIObjectType.UILabel.name()) ||
                    objectType.equals(UIObjectType.UILink.name()) ||
                    objectType.equals(UIObjectType.UIRadioButton.name()) ||
                    objectType.equals(UIObjectType.UITextArea.name()) ||
                    objectType.equals(UIObjectType.UITextBox.name())) {
                constArgs = new Object[2];
                constArgs[0] = objectId;
                value = (String) getValueFromDataObject(object);
                if (value != null) {
                    constArgs[1] = value;
                } else {//get default value

                    DynamicMapParameter parValue = object.getParameterByName(
                            UIObjectParameter.Value.name());
                    value = getParameterValue(parValue);
                    constArgs[1] = value;
                }
            } else if (objectType.equals(UIObjectType.WaitForCondition.name()) ||
                    objectType.equals(UIObjectType.WaitForPopup.name()) ||
                    objectType.equals(UIObjectType.WaitForFrameToLoad.name()) ||
                    objectType.equals(UIObjectType.WaitForPageLoad.name()) ||
                    objectType.equals(UIObjectType.UIRequireRebootTimeout.name()) ||
                    objectType.equals(UIObjectType.UIInformationAlert.name()) ||
                    objectType.equals(UIObjectType.UIPromptAnswer.name()) ||
                    objectType.equals(UIObjectType.UIValidationAlert.name()) ||
                    objectType.equals(UIObjectType.UIWindow.name()) ||
                    objectType.equals(UIObjectType.UIPopupClosed.name()) ||
                    objectType.equals(UIObjectType.UIConfirmationAlert.name())) {
                ArrayList<String> lstParValues =
                        new ArrayList<String>();
                params = object.getParameters();
                for (int parIndex = 0; parIndex < params.length;
                        parIndex++) {
                    if (params[parIndex].getParameter().getUseForConstructor()) {
                        lstParValues.add(params[parIndex].getValue());
                    }
                }
                constArgs = new Object[lstParValues.size()];
                for (int j = 0; j < constArgs.length;
                        j++) {
                    constArgs[j] = new String(lstParValues.get(j));
                }
            } else if (objectType.equals(UIObjectType.UICheckBoxGroup.name()) ||
                    objectType.equals(UIObjectType.UIRadioButtonGroup.name()) ||
                    objectType.equals(UIObjectType.UIDropDown.name()) ||
                    objectType.equals(UIObjectType.UIMultiSelectListBox.name())) {
                constArgs = new Object[2];
                constArgs[0] = objectId;
                value = (String) getValueFromDataObject(object);
                if (value != null) {
                    if (!value.equals("")) {
                        value = convertAbstractIds(value);
                    }
                } else {
                    value = "";
                }
                constArgs[1] = value;
            } else {
                constArgs = null;
            }
            if (constArgs != null && !isObjectDynamic) {
                lstData.add(new WebAutomationModuleDataNode(
                        objectType,
                        constArgs,
                        abstractId));
            } else if (constArgs != null) {
                lstData.add(new WebAutomationModuleDataNode(
                        "UIDynamicObject",
                        constArgs,
                        abstractId));
            }

        }
    }

    public DynamicMapDesignTreeNode findObject(String abstractId) {
        return m_root.searchObject(UIObjectParameter.AbstractId.name(),
                abstractId);
    }

    public boolean isObjectDynamic(DynamicMapObject object) {
        DynamicMapParameter parIsDynamic = object.getParameterByName(
                UIObjectParameter.IsDynamic.name());
        if (parIsDynamic == null) {
            return false;
        }
        String value = getParameterValue(parIsDynamic);
        if ("1".equals(value)) {
            return true;
        }
        return false;
    }

    public boolean isObjectInPopupWindow(
            ArrayList<DynamicMapDesignTreeNode> path) {
        if (path.size() < 1) {
            return false;
        }
        if (path.get(0).getObject().getTypeName().equals(UIObjectType.UIWindow.name())) {
            return true;
        }
        return false;
    }

    public void findObjectPath(ArrayList<DynamicMapDesignTreeNode> path,
            DynamicMapDesignTreeNode object) {

        if (object == null) {
            return;
        }
        findObjectPath(path,
                object.getParent());
        if (object != null) {
            if (!object.getObject().getTypeName().equals(
                    UIObjectType.UIDynamicGrid.name())) {
                path.add(object);

            }
        }
        return;
    }

    public String convertAbstractIds(String value) {
        boolean isStartWithcontains = false;
        if (value.startsWith("CONTAINS")) {
            isStartWithcontains = true;

            int startIdx = value.indexOf("(");
            int endIdx = value.lastIndexOf(")");
            if (startIdx >= 0 && endIdx > 0) {
                value = value.substring(startIdx + 1,
                        endIdx);
            } else {
                return value;
            }
        }
        String[] values = value.split(
                AtofModuleConstants.PARAM_SEP_SPLIT_STR);
        String output = "", temp = "";
        DynamicMapDesignTreeNode objNode;
        DynamicMapObject obj;
        for (int i = 0;
                i < values.length;
                i++) {
            objNode = findObject(values[i]);
            if (objNode != null &&
                    !values[i].equals("")) {
                obj = objNode.getObject();
                temp = getObjectId(obj);
            } else {
                temp = values[i];
            }
            if (output.equals("")) {
                output = temp;
            } else {
                output = output + AtofModuleConstants.PARAM_SEP_STR +
                        temp;
            }
        }
        if (isStartWithcontains) {
            output = "CONTAINS(" + output + ")";
        }
        return output;
    }

    public Object getValueFromDataObject(
            DynamicMapObject object) {
        DynamicMapParameter parAbstractId = object.getParameterByName(
                UIObjectParameter.AbstractId.name());
        String abstractId = getParameterValue(parAbstractId);
        String value = m_data.getDataToApply().get(abstractId);
        return value;
    }

    public String getObjectId(
            DynamicMapObject object) {
        DynamicMapParameter parId = object.getParameterByName(
                UIObjectParameter.Id.name());
        DynamicMapParameter parXPath = object.getParameterByName(
                UIObjectParameter.Xpath.name());
        String id = getParameterValue(parId);
        String xpath = getParameterValue(parXPath);
        if (id == null || id.equals("")) {
            return xpath;
        }


        return id;
    }

    public String getAbstractId(
            DynamicMapObject object) {
        DynamicMapParameter parAbstractId = object.getParameterByName(
                UIObjectParameter.AbstractId.name());
        String id = getParameterValue(parAbstractId);

        return id;
    }

    public String getParameterValue(
            DynamicMapParameter parameter) {
        if (parameter == null) {
            return null;
        }
        if (parameter.getReference() == null) {
            return "";
        }
        return parameter.getValue();
    }
}
